package text;

import mathsys2.ExerciseSet;
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.*;

/**
 * 习题类单元测试：《面向对象软件构造》2.4节需求
 * 覆盖50道加法/减法/混合习题的生成、校验与显示
 */
public class ExerciseSetTest {
    private static final int EXERCISE_COUNT = 50;

    // 测试1：生成50道加法习题（数量、去重、结果）
    @Test
    void testGenerateAdditions() {
        ExerciseSet addSet = new ExerciseSet(EXERCISE_COUNT, false);
        addSet.generateAdditions();

        assertEquals(EXERCISE_COUNT, addSet.getGeneratedCount(), "加法习题数量不为50道");
        assertFalse(addSet.hasDuplicate(), "加法习题存在重复");
        assertTrue(addSet.isResultValid(), "加法习题存在结果超100");
    }

    // 测试2：生成50道减法习题（数量、去重、结果）
    @Test
    void testGenerateSubtractions() {
        ExerciseSet subSet = new ExerciseSet(EXERCISE_COUNT, false);
        subSet.generateSubtractions();

        assertEquals(EXERCISE_COUNT, subSet.getGeneratedCount(), "减法习题数量不为50道");
        assertFalse(subSet.hasDuplicate(), "减法习题存在重复");
        assertTrue(subSet.isResultValid(), "减法习题存在结果为负");
    }

    // 测试3：生成50道混合习题（数量、比例、去重、结果）
    @Test
    void testGenerateMixedExercises() {
        ExerciseSet mixedSet = new ExerciseSet(EXERCISE_COUNT, true);
        mixedSet.generateMixedExercises();

        // 数量校验
        assertEquals(EXERCISE_COUNT, mixedSet.getGeneratedCount(), "混合习题数量不为50道");
        // 比例校验（24-26道加法）
        long addCount = mixedSet.getExercises().stream().filter(a -> a.getOperator() == '+').count();
        assertTrue(addCount >=24 && addCount <=26, "混合习题加法比例失衡");
        // 去重与结果校验
        assertFalse(mixedSet.hasDuplicate(), "混合习题存在重复");
        assertTrue(mixedSet.isResultValid(), "混合习题存在结果违规");
    }

    // 测试4：格式化显示无异常（正常场景）
    @Test
    void testPrintExercises() {
        ExerciseSet addSet = new ExerciseSet(EXERCISE_COUNT, false);
        addSet.generateAdditions();

        assertDoesNotThrow(() -> addSet.printExercises(5), "每行5道显示时抛出异常");
        assertDoesNotThrow(() -> addSet.printExercises(10), "每行10道显示时抛出异常");
    }

    // 测试5：非法数量构造（非50道）
    @Test
    void testInvalidCount_ThrowsException() {
        assertThrows(IllegalArgumentException.class,
                () -> new ExerciseSet(49, false),
                "构造非50道习题集未抛出异常");
    }
}